import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Random;

// 游戏面板类
public class GamePanel extends JPanel implements ActionListener, KeyListener {
    public static final int WIDTH = 640;
    public static final int HEIGHT = 640;

    private Timer timer;
    private ArrayList<Tank> tanks;
    private ArrayList<Bullet> bullets;
    private ArrayList<Explosion> explosions;
    private ArrayList<Wall> walls;
    private Base base;
    private Tank playerTank;
    private boolean gameOver;
    private int score;
    private int enemyCount;
    private int wave;
    private Random random;
    private BufferedImage backgroundImage;
    private boolean upPressed, downPressed, leftPressed, rightPressed;

    public GamePanel() {
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setBackground(Color.BLACK);
        setFocusable(true);
        addKeyListener(this);

        timer = new Timer(16, this); // 约60帧每秒
        random = new Random();

        // 加载背景图片
        backgroundImage = ImageManager.getImage("background.jpg");

        startGame();
    }

    public void startGame() {
        tanks = new ArrayList<>();
        bullets = new ArrayList<>();
        explosions = new ArrayList<>();
        walls = new ArrayList<>();
        gameOver = false;
        score = 0;
        enemyCount = 5;
        wave = 1;
        upPressed = downPressed = leftPressed = rightPressed = false;

        // 创建玩家坦克
        playerTank = new Tank(WIDTH / 2, HEIGHT - 100, 40, 40, Tank.Direction.UP, 8, Color.GREEN, false);
        tanks.add(playerTank);

        // 创建基地
        base = new Base(WIDTH / 2 - 20, HEIGHT - 40, 40, 40);

        // 创建墙壁
        createWalls();

        // 创建敌人
        spawnEnemies(enemyCount);

        // 播放开始音效
        SoundManager.playSound("start.wav");

        // 播放背景音乐
        SoundManager.playBackgroundMusic("background.wav");

        timer.start();
    }

    private void createWalls() {
        // 清空现有墙壁
        walls.clear();

        // 创建地图边界
        for (int x = 0; x < WIDTH; x += 40) {
            walls.add(new Wall(x, 0, 40, 40, Wall.WallType.STEEL));
            walls.add(new Wall(x, HEIGHT - 40, 40, 40, Wall.WallType.STEEL));
        }

        for (int y = 40; y < HEIGHT - 40; y += 40) {
            walls.add(new Wall(0, y, 40, 40, Wall.WallType.STEEL));
            walls.add(new Wall(WIDTH - 40, y, 40, 40, Wall.WallType.STEEL));
        }

        // 创建基地周围的保护墙
        for (int x = WIDTH / 2 - 80; x <= WIDTH / 2 + 40; x += 40) {
            for (int y = HEIGHT - 80; y <= HEIGHT - 40; y += 40) {
                if (x != WIDTH / 2 || y != HEIGHT - 40) {
                    walls.add(new Wall(x, y, 40, 40, Wall.WallType.BRICK));
                }
            }
        }

        // 创建随机墙壁
        int wallCount = 30;
        for (int i = 0; i < wallCount; i++) {
            Wall.WallType type = random.nextBoolean() ? Wall.WallType.BRICK : Wall.WallType.STEEL;
            int x = 40 + random.nextInt((WIDTH - 80) / 40) * 40;
            int y = 40 + random.nextInt((HEIGHT - 160) / 40) * 40;

            // 确保墙壁不会与玩家坦克或基地重叠
            Tank tempTank = new Tank(x, y, 40, 40, Tank.Direction.UP, 0, Color.BLACK, false);
            if (!tempTank.intersects(playerTank) && !tempTank.intersects(base)) {
                walls.add(new Wall(x, y, 40, 40, type));
            }
        }

        // 添加水域
        int waterCount = 10;
        for (int i = 0; i < waterCount; i++) {
            int x = 40 + random.nextInt((WIDTH - 80) / 40) * 40;
            int y = 40 + random.nextInt((HEIGHT - 160) / 40) * 40;

            // 确保水域不会与玩家坦克或基地重叠
            Tank tempTank = new Tank(x, y, 40, 40, Tank.Direction.UP, 0, Color.BLACK, false);
            if (!tempTank.intersects(playerTank) && !tempTank.intersects(base)) {
                walls.add(new Wall(x, y, 40, 40, Wall.WallType.WATER));
            }
        }
    }

    private void spawnEnemies(int count) {
        for (int i = 0; i < count; i++) {
            int x = 40 + random.nextInt((WIDTH - 80) / 40) * 40;
            int y = 40 + random.nextInt(3) * 40;

            // 确保敌人不会与其他坦克或墙壁重叠
            boolean overlap = false;
            Tank tempTank = new Tank(x, y, 40, 40, Tank.Direction.DOWN, 0, Color.RED, true);
            for (Tank tank : tanks) {
                if (tempTank.intersects(tank)) {
                    overlap = true;
                    break;
                }
            }
            for (Wall wall : walls) {
                if (tempTank.intersects(wall)) {
                    overlap = true;
                    break;
                }
            }

            if (!overlap) {
                tanks.add(new Tank(x, y, 40, 40, Tank.Direction.DOWN, 3, Color.RED, true));
            }
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (gameOver) {
            return;
        }

        // 处理玩家坦克长按移动
        if (upPressed) playerTank.setDirection(Tank.Direction.UP);
        if (downPressed) playerTank.setDirection(Tank.Direction.DOWN);
        if (leftPressed) playerTank.setDirection(Tank.Direction.LEFT);
        if (rightPressed) playerTank.setDirection(Tank.Direction.RIGHT);
        if (upPressed || downPressed || leftPressed || rightPressed) {
            playerTank.move(walls, tanks, base);
        }
        playerTank.update();

        // 更新敌人坦克
        for (int i = 0; i < tanks.size(); i++) {
            Tank tank = tanks.get(i);
            if (tank.isEnemy()) {
                // 随机改变方向
                if (random.nextInt(100) < 3) {
                    Tank.Direction[] directions = Tank.Direction.values();
                    tank.setDirection(directions[random.nextInt(directions.length)]);
                }

                // 随机射击
                if (random.nextInt(100) < 5) {
                    Bullet bullet = tank.fire();
                    if (bullet != null) {
                        bullets.add(bullet);
                    }
                }

                tank.move(walls, tanks, base);
                tank.update();
            }
        }

        // 更新子弹
        for (int i = bullets.size() - 1; i >= 0; i--) {
            Bullet bullet = bullets.get(i);
            bullet.update();

            // 检查子弹是否超出边界
            if (bullet.isOutOfBounds()) {
                bullets.remove(i);
                continue;
            }

            // 检查子弹是否击中墙壁
            boolean hitWall = false;
            for (int j = walls.size() - 1; j >= 0; j--) {
                Wall wall = walls.get(j);
                if (bullet.intersects(wall)) {
                    hitWall = true;

                    // 如果是砖块墙，移除它
                    if (wall.isDestroyable()) {
                        walls.remove(j);
                        explosions.add(new Explosion(wall.getX(), wall.getY(), 40, 40));
                    }

                    bullets.remove(i);
                    break;
                }
            }

            if (hitWall) {
                continue;
            }

            // 检查子弹是否击中坦克
            for (int j = tanks.size() - 1; j >= 0; j--) {
                Tank tank = tanks.get(j);
                if (bullet.intersects(tank) && bullet.isEnemy() != tank.isEnemy()) {
                    // 播放爆炸音效
                    SoundManager.playSound("explosion.wav");

                    explosions.add(new Explosion(tank.getX(), tank.getY(), 40, 40));
                    bullets.remove(i);

                    // 如果是玩家坦克被击中，游戏结束
                    if (!tank.isEnemy()) {
                        gameOver = true;
                        SoundManager.stopBackgroundMusic();
                        SoundManager.playSound("gameover.wav");
                    } else {
                        // 如果是敌人坦克被击中，增加分数
                        score += 100;
                        tanks.remove(j);

                        // 检查是否所有敌人都被消灭
                        boolean allEnemiesDestroyed = true;
                        for (Tank t : tanks) {
                            if (t.isEnemy()) {
                                allEnemiesDestroyed = false;
                                break;
                            }
                        }

                        // 如果所有敌人都被消灭，开始新的一波
                        if (allEnemiesDestroyed) {
                            wave++;
                            enemyCount += 2;
                            spawnEnemies(enemyCount);
                            createWalls();
                        }
                    }

                    break;
                }
            }

            // 检查子弹是否击中基地
            if (base != null && bullet.intersects(base)) {
                explosions.add(new Explosion(base.getX(), base.getY(), 40, 40));
                bullets.remove(i);
                base = null;
                gameOver = true;
                SoundManager.stopBackgroundMusic();
                SoundManager.playSound("gameover.wav");
            }
        }

        // 更新爆炸效果
        for (int i = explosions.size() - 1; i >= 0; i--) {
            Explosion explosion = explosions.get(i);
            explosion.update();
            if (explosion.isFinished()) {
                explosions.remove(i);
            }
        }

        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        // 绘制背景
        if (backgroundImage != null) {
            g.drawImage(backgroundImage, 0, 0, WIDTH, HEIGHT, null);
        } else {
            g.setColor(new Color(0, 30, 0));
            g.fillRect(0, 0, WIDTH, HEIGHT);
        }

        // 绘制墙壁
        for (Wall wall : walls) {
            wall.draw(g);
        }

        // 绘制基地
        if (base != null) {
            base.draw(g);
        }

        // 绘制坦克
        for (Tank tank : tanks) {
            tank.draw(g);
        }

        // 绘制子弹
        for (Bullet bullet : bullets) {
            bullet.draw(g);
        }

        // 绘制爆炸效果
        for (Explosion explosion : explosions) {
            explosion.draw(g);
        }

        // 绘制游戏信息
        g.setColor(Color.WHITE);
        g.setFont(new Font("Arial", Font.BOLD, 20));
        g.drawString("分数: " + score, 20, 30);
        g.drawString("波数: " + wave, 20, 60);
        g.drawString("敌人: " + (enemyCount - (tanks.size() - 1)), 20, 90);

        // 绘制游戏结束信息
        if (gameOver) {
            g.setColor(new Color(255, 0, 0, 180));
            g.fillRect(WIDTH / 2 - 150, HEIGHT / 2 - 50, 300, 100);

            g.setColor(Color.WHITE);
            g.setFont(new Font("Arial", Font.BOLD, 30));
            g.drawString("游戏结束!", WIDTH / 2 - 100, HEIGHT / 2);

            g.setFont(new Font("Arial", Font.BOLD, 20));
            g.drawString("按 R 键重新开始", WIDTH / 2 - 120, HEIGHT / 2 + 30);
        }
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (gameOver) {
            if (e.getKeyCode() == KeyEvent.VK_R) {
                startGame();
            }
            return;
        }

        int key = e.getKeyCode();

        switch(key) {
            case KeyEvent.VK_UP: upPressed = true; break;
            case KeyEvent.VK_DOWN: downPressed = true; break;
            case KeyEvent.VK_LEFT: leftPressed = true; break;
            case KeyEvent.VK_RIGHT: rightPressed = true; break;
            case KeyEvent.VK_SPACE:
                Bullet bullet = playerTank.fire();
                if (bullet != null) {
                    bullets.add(bullet);
                }
                break;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();
        switch(key) {
            case KeyEvent.VK_UP: upPressed = false; break;
            case KeyEvent.VK_DOWN: downPressed = false; break;
            case KeyEvent.VK_LEFT: leftPressed = false; break;
            case KeyEvent.VK_RIGHT: rightPressed = false; break;
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {
        // 不处理
    }
}